import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { config } from '../config';
import { prisma } from '../lib/prisma';

// 扩展Request类型以包含用户信息
declare global {
  namespace Express {
    interface Request {
      user: {
        id: string;
        username: string;
        email: string;
        role: string;
      };
    }
  }
}

// JWT认证中间件
export const authenticateToken = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const authHeader = req.headers.authorization;
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      return res.status(401).json({ 
        success: false, 
        error: '访问令牌缺失' 
      });
    }

    // 验证JWT令牌
    const decoded = jwt.verify(token, config.JWT_SECRET) as any;
    
    // 检查用户是否存在且状态正常
    const user = await prisma.user.findUnique({
      where: { id: decoded.userId },
      select: {
        id: true,
        username: true,
        email: true,
        role: true,
        status: true
      }
    });

    if (!user) {
      return res.status(401).json({ 
        success: false, 
        error: '用户不存在' 
      });
    }

    if (user.status !== 'ACTIVE') {
      return res.status(401).json({ 
        success: false, 
        error: '账户已被禁用' 
      });
    }

    // 将用户信息添加到请求对象
    req.user = {
      id: user.id,
      username: user.username,
      email: user.email,
      role: user.role
    };

    next();
  } catch (error) {
    if (error instanceof jwt.JsonWebTokenError) {
      return res.status(401).json({ 
        success: false, 
        error: '无效的访问令牌' 
      });
    }
    
    if (error instanceof jwt.TokenExpiredError) {
      return res.status(401).json({ 
        success: false, 
        error: '访问令牌已过期' 
      });
    }

    console.error('认证中间件错误:', error);
    return res.status(500).json({ 
      success: false, 
      error: '认证服务错误' 
    });
  }
};

// 角色授权中间件
export const authorizeRole = (allowedRoles: string[]) => {
  return (req: Request, res: Response, next: NextFunction) => {
    if (!req.user) {
      return res.status(401).json({ 
        success: false, 
        error: '未认证' 
      });
    }

    if (!allowedRoles.includes(req.user.role)) {
      return res.status(403).json({ 
        success: false, 
        error: '权限不足' 
      });
    }

    next();
  };
};

// 可选认证中间件（不强制要求认证）
export const optionalAuth = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const authHeader = req.headers.authorization;
    const token = authHeader && authHeader.split(' ')[1];

    if (token) {
      try {
        const decoded = jwt.verify(token, config.JWT_SECRET) as any;
        
        const user = await prisma.user.findUnique({
          where: { id: decoded.userId },
          select: {
            id: true,
            username: true,
            email: true,
            role: true,
            status: true
          }
        });

        if (user && user.status === 'ACTIVE') {
          req.user = {
            id: user.id,
            username: user.username,
            email: user.email,
            role: user.role
          };
        }
      } catch (error) {
        // 令牌无效，但不影响继续执行
        console.log('可选认证失败:', error);
      }
    }

    next();
  } catch (error) {
    console.error('可选认证中间件错误:', error);
    next(); // 继续执行，不中断请求
  }
};

// 检查资源所有权中间件
export const checkOwnership = (resourceType: 'knowledgeBase' | 'file' | 'comment') => {
  return async (req: Request, res: Response, next: NextFunction) => {
    try {
      if (!req.user) {
        return res.status(401).json({ 
          success: false, 
          error: '未认证' 
        });
      }

      // 管理员可以操作所有资源
      if (req.user.role === 'ADMIN') {
        return next();
      }

      const resourceId = req.params.id;
      let resource: any;

      // 根据资源类型查询
      switch (resourceType) {
        case 'knowledgeBase':
          resource = await prisma.knowledgeBase.findUnique({
            where: { id: resourceId },
            select: { authorId: true }
          });
          break;
        case 'file':
          resource = await prisma.fileUpload.findUnique({
            where: { id: resourceId },
            select: { uploadedById: true }
          });
          break;
        case 'comment':
          resource = await prisma.comment.findUnique({
            where: { id: resourceId },
            select: { authorId: true }
          });
          break;
        default:
          return res.status(400).json({ 
            success: false, 
            error: '无效的资源类型' 
          });
      }

      if (!resource) {
        return res.status(404).json({ 
          success: false, 
          error: '资源不存在' 
        });
      }

      // 检查是否是资源所有者
      const ownerId = resource.authorId || resource.uploadedById;
      if (ownerId !== req.user.id) {
        return res.status(403).json({ 
          success: false, 
          error: '没有权限操作此资源' 
        });
      }

      next();
    } catch (error) {
      console.error('检查资源所有权失败:', error);
      return res.status(500).json({ 
        success: false, 
        error: '权限检查失败' 
      });
    }
  };
};

// 检查用户状态中间件
export const checkUserStatus = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    if (!req.user) {
      return res.status(401).json({ 
        success: false, 
        error: '未认证' 
      });
    }

    const user = await prisma.user.findUnique({
      where: { id: req.user.id },
      select: { status: true }
    });

    if (!user) {
      return res.status(401).json({ 
        success: false, 
        error: '用户不存在' 
      });
    }

    if (user.status !== 'ACTIVE') {
      return res.status(403).json({ 
        success: false, 
        error: '账户已被禁用，无法执行此操作' 
      });
    }

    next();
  } catch (error) {
    console.error('检查用户状态失败:', error);
    return res.status(500).json({ 
      success: false, 
      error: '状态检查失败' 
    });
  }
};
